package com.kelvem.saas.workbanch.ontology.waybill.service;

import com.kelvem.saas.workbanch.core.exception.SaasException;
import com.kelvem.saas.workbanch.ontology.address.map.baidu.BaiduMapApi;
import com.kelvem.saas.workbanch.ontology.address.map.baidu.PlaceInfo;
import com.kelvem.saas.workbanch.ontology.address.map.baidu.RouteInfo;
import com.kelvem.saas.workbanch.ontology.carrier.model.LineOfferEntity;
import com.kelvem.saas.workbanch.ontology.carrier.service.LineOfferService;
import com.kelvem.saas.workbanch.ontology.piaoorder.request.PiaoOrderAddressReq;
import com.kelvem.saas.workbanch.ontology.piaoorder.request.PiaoOrderGoodsReq;
import com.kelvem.saas.workbanch.ontology.piaoorder.request.PiaoOrderReq;
import com.kelvem.saas.workbanch.ontology.waybill.dao.WaybillDao;
import com.kelvem.saas.workbanch.ontology.waybill.model.WaybillEntity;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class WaybillService {
    
    @Resource
    private WaybillDao waybillDao;
    
    @Resource
    private LineOfferService lineOfferService;
    
    public Integer duration(PiaoOrderAddressReq address) {
        LineOfferEntity lineOffer = lineOfferService.getLineOffer(address.getProvince(), address.getCity(), address.getCounty());
        if (lineOffer == null) {
            String message = String.format("lineOfferService.getLineOffer, err, province=%s, city=%s, county=%s, ", address.getProvince(), address.getCity(), address.getCounty());
            log.error(message);
            throw new SaasException(message);
        }
        return lineOffer.getQuanchengShixiao().multiply(new BigDecimal(24 * 60 * 60)).intValue();
    }
    
    public List<WaybillEntity> match(PiaoOrderReq order) {
    
        List<WaybillEntity> waybillList = new ArrayList<WaybillEntity>();
        
        String pickType = order.getPickType();
        String deliveryType = order.getDeliveryType();
    
        PiaoOrderAddressReq sender = order.getSender();
        PiaoOrderAddressReq receiver = order.getReceiver();
        PiaoOrderGoodsReq goods = order.getGoods();
    
        /**
         * 取货
         */
        if ("1".equals(pickType)) {
            WaybillEntity pickWaybill = buildPickWaybill(sender, goods);
            waybillList.add(pickWaybill);
        }
    
        /**
         * 支线
         */
        WaybillEntity branchWaybill = buildBranchWaybill(receiver, goods);
        waybillList.add(branchWaybill);
    
        /**
         * 干线
         */
        WaybillEntity trunkWaybill = buildTrunkWaybill(receiver, goods);
        waybillList.add(trunkWaybill);
    
        /**
         * 送货
         */
        if ("1".equals(deliveryType)) {
            WaybillEntity pickWaybill = buildDeliveryWaybill(receiver, goods);
            waybillList.add(pickWaybill);
        }
    
        return waybillList;
    }
    
    private WaybillEntity buildPickWaybill(PiaoOrderAddressReq sender, PiaoOrderGoodsReq goods) {
    
        WaybillEntity waybill = new WaybillEntity();
        waybill.setWaybillNo("");
        waybill.setWaybillType("取货");
        waybill.setRouteType("陆运");
        waybill.setOwnerType("自营");
    
        // 滕州线路报价
        LineOfferEntity lineOffer = lineOfferService.getLineOfferById(10000L);
        if (lineOffer == null) {
            String message = "lineOfferService.getLineOfferById, err, lineOfferId=" + 10000;
            log.error(message);
            throw new SaasException(message);
        }
    
        // heavy(kg) = max(重量, 体积重量)
        Pair<String, BigDecimal> heavyPair = calHeavy(goods);
        waybill.setHeavyType(heavyPair.getLeft());
        waybill.setHeavy(heavyPair.getRight());
        
        // 枣庄市-滕州市-嘉誉国际商贸城
        // 35.112029  117.155298
        // 发货地址 -> 滕州收货点
        RouteInfo route = BaiduMapApi.calRouteInfo(sender.getLat(), sender.getLng(), new BigDecimal(35.112029), new BigDecimal(117.155298));
        
        Integer distance = route.getDistance();
    
        /**
         * MAX( N单价元/吨 * max(重量, 体积重量) +（T公里-5）*续费公里/元)，起步价)
         */
        BigDecimal estimatePrice = new BigDecimal(0);
        
        // MAX( N单价元/吨 * max(重量, 体积重量)
        BigDecimal heavy = heavyPair.getRight();
        estimatePrice = estimatePrice.add(heavy.multiply(lineOffer.getQuhuoWeight()).divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP));
    
        //（T公里-5）*续费公里/元)
        BigDecimal distancePrice = calPickDistancePrice(lineOffer, distance);
        estimatePrice = estimatePrice.add(distancePrice);
    
        // 货品加价 markup
        BigDecimal markup = calGoodsTypeMarkup(goods);
        estimatePrice = estimatePrice.multiply(markup);
        
        // MAX(计算值，起步价)
        if (estimatePrice.compareTo(lineOffer.getQuhuoQibujia()) < 0) {
            estimatePrice = lineOffer.getQuhuoQibujia();
        }
    
        waybill.setDistance(route.getDistance());
        waybill.setDuration(0);
        waybill.setEstimatePrice(estimatePrice);
        waybill.setPaymentPrice(null);
        waybill.setRealPrice(null);
    
        waybill.setSrcProvince(sender.getProvince());
        waybill.setSrcCity(sender.getCity());
        waybill.setSrcCounty(sender.getCounty());
        waybill.setSrcAddressDetail(sender.getAddressDetail());
        waybill.setSrcAreaCode(sender.getAreaCode());
        waybill.setSrcStationId(null);
        
        waybill.setDstProvince("山东省");
        waybill.setDstCity("枣庄市");
        waybill.setDstCounty("滕州市");
        waybill.setDstAddressDetail("新华后街永腾物流");
        waybill.setDstAreaCode("370481");
        waybill.setDstStationId(10000L);
        
        waybill.setState("pending");
        waybill.setStateTime(new Date());
        waybill.setCreateTime(new Date());
        waybill.setUpdateTime(new Date());
        
        return waybill;
    }
    
    private WaybillEntity buildDeliveryWaybill(PiaoOrderAddressReq receiver, PiaoOrderGoodsReq goods) {
        
        WaybillEntity waybill = new WaybillEntity();
        waybill.setWaybillNo("");
        waybill.setWaybillType("送货");
        waybill.setRouteType("陆运");
        waybill.setOwnerType("外包");
        
        // 送货地址线路报价
        LineOfferEntity lineOffer = lineOfferService.getLineOffer(receiver.getProvince(), receiver.getCity(), receiver.getCounty());
        if (lineOffer == null) {
            String message = String.format("lineOfferService.getLineOffer, err, province=%s, city=%s, county=%s, ", receiver.getProvince(), receiver.getCity(), receiver.getCounty());
            log.error(message);
            throw new SaasException(message);
        }
    
        // heavy(kg) = max(重量, 体积重量)
        Pair<String, BigDecimal> heavyPair = calHeavy(goods);
        waybill.setHeavyType(heavyPair.getLeft());
        waybill.setHeavy(heavyPair.getRight());
        
        // 收货地址的市区中心 -> 收货地址
        PlaceInfo place = BaiduMapApi.calPlaceInfo(receiver.getProvince() + receiver.getCity() + receiver.getCounty(), receiver.getCity());
        RouteInfo route = BaiduMapApi.calRouteInfo(place.getLat(), place.getLng(), receiver.getLat(), receiver.getLng());
        
        Integer distance = route.getDistance();
        
        /**
         * MAX( N单价元/吨 * max(重量, 体积重量) +（T公里-5）*续费公里/元)，起步价)
         */
        BigDecimal estimatePrice = new BigDecimal(0);
        
        // MAX( N单价元/吨 * max(重量, 体积重量)
        BigDecimal heavy = heavyPair.getRight();
        estimatePrice = estimatePrice.add(heavy.multiply(lineOffer.getQuhuoWeight()).divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP));
        
        //（T公里-5）* 续费公里/元)
        BigDecimal distancePrice = calPickDistancePrice(lineOffer, distance);
        estimatePrice = estimatePrice.add(distancePrice);
        
        // 货品加价 markup
        BigDecimal markup = calGoodsTypeMarkup(goods);
        estimatePrice = estimatePrice.multiply(markup);
        
        // MAX(计算值，起步价)
        if (estimatePrice.compareTo(lineOffer.getQuhuoQibujia()) < 0) {
            estimatePrice = lineOffer.getQuhuoQibujia();
        }
        
        waybill.setDistance(route.getDistance());
        waybill.setDuration(0);
        waybill.setEstimatePrice(estimatePrice);
        waybill.setPaymentPrice(null);
        waybill.setRealPrice(null);
    
        waybill.setSrcProvince(place.getProvince());
        waybill.setSrcCity(place.getCity());
        waybill.setSrcCounty(place.getDistrict());
        waybill.setSrcAddressDetail(place.getName());
        waybill.setSrcAreaCode(place.getAdcode());
        waybill.setSrcStationId(null);
        
        waybill.setDstProvince(receiver.getProvince());
        waybill.setDstCity(receiver.getCity());
        waybill.setDstCounty(receiver.getCounty());
        waybill.setDstAddressDetail(receiver.getAddressDetail());
        waybill.setDstAreaCode(receiver.getAreaCode());
        waybill.setDstStationId(null);
        
        waybill.setState("pending");
        waybill.setStateTime(new Date());
        waybill.setCreateTime(new Date());
        waybill.setUpdateTime(new Date());
        
        return waybill;
    }
    
    private WaybillEntity buildBranchWaybill(PiaoOrderAddressReq receiver, PiaoOrderGoodsReq goods) {
        
        WaybillEntity waybill = new WaybillEntity();
        waybill.setWaybillNo("");
        waybill.setWaybillType("支线");
        waybill.setRouteType("陆运");
        waybill.setOwnerType("自营");
        
        // 滕州线路报价
        LineOfferEntity lineOffer = lineOfferService.getLineOffer(receiver.getProvince(), receiver.getCity(), receiver.getCounty());
        if (lineOffer == null) {
            String message = "lineOfferService.getLineOfferById, err, lineOfferId=" + 10000;
            log.error(message);
            throw new SaasException(message);
        }
    
        // heavy(kg) = max(重量, 体积重量)
        Pair<String, BigDecimal> heavyPair = calHeavy(goods);
        waybill.setHeavyType(heavyPair.getLeft());
        waybill.setHeavy(heavyPair.getRight());
    
        // 枣庄市-滕州市-嘉誉国际商贸城
        // 35.112029  117.155298
        // 临沂市-兰山区-兰山街道办事处
        // 35.1165    118.266583
        // 滕州收货点 -> 临沂散货点
        RouteInfo route = BaiduMapApi.calRouteInfo(new BigDecimal(35.112029), new BigDecimal(117.155298), new BigDecimal(35.1165), new BigDecimal(118.266583));
    
        /**
         * N单价元/吨 * max(重量, 体积重量) * 折扣率
         */
        // heavy * (直达重货价格 + 中转重货价格) * discount
        BigDecimal heavy = heavyPair.getRight();
        BigDecimal discount = calWeightDiscount(lineOffer, heavy);
        BigDecimal zhonghuoJiage = new BigDecimal(lineOffer.getZhixianZhongJiage());
        BigDecimal totalJiage = new BigDecimal(lineOffer.getGanxianZhongJiage()).add(new BigDecimal(lineOffer.getZhongzhuanZhongJiage())).add(new BigDecimal(lineOffer.getZhixianZhongJiage()));
    
        BigDecimal estimatePrice = heavy.multiply(zhonghuoJiage).divide(totalJiage, 2, RoundingMode.HALF_UP);
        estimatePrice = estimatePrice.multiply(discount);
    
        // 货品加价 markup
        BigDecimal markup = calGoodsTypeMarkup(goods);
        estimatePrice = estimatePrice.multiply(markup);
        
        // MAX(计算值，起步价)
        if (estimatePrice.compareTo(new BigDecimal(lineOffer.getQibuJiage())) < 0) {
            estimatePrice = new BigDecimal(lineOffer.getQibuJiage());
        }
        
        waybill.setDistance(route.getDistance());
        waybill.setDuration(0);
        waybill.setEstimatePrice(estimatePrice);
        waybill.setPaymentPrice(null);
        waybill.setRealPrice(null);
        
        waybill.setSrcProvince("山东省");
        waybill.setSrcCity("枣庄市");
        waybill.setSrcCounty("滕州市");
        waybill.setSrcAddressDetail("新华后街永腾物流");
        waybill.setSrcAreaCode("370481");
        waybill.setSrcStationId(10001L);
        
        waybill.setDstProvince("山东省");
        waybill.setDstCity("临沂市");
        waybill.setDstCounty("兰山区");
        waybill.setDstAddressDetail("临西十二路兰山街道办事处朱许小学东南420米");
        waybill.setDstAreaCode("371302");
        waybill.setDstStationId(10001L);
        
        waybill.setState("pending");
        waybill.setStateTime(new Date());
        waybill.setCreateTime(new Date());
        waybill.setUpdateTime(new Date());
        
        return waybill;
    }
    
    private WaybillEntity buildTrunkWaybill(PiaoOrderAddressReq receiver, PiaoOrderGoodsReq goods) {
        
        WaybillEntity waybill = new WaybillEntity();
        waybill.setWaybillNo("");
        waybill.setWaybillType("干线");
        waybill.setRouteType("陆运");
        waybill.setOwnerType("外包");
        
        // 送货地址线路报价
        LineOfferEntity lineOffer = lineOfferService.getLineOffer(receiver.getProvince(), receiver.getCity(), receiver.getCounty());
        if (lineOffer == null) {
            String message = String.format("lineOfferService.getLineOffer, err, province=%s, city=%s, county=%s, ", receiver.getProvince(), receiver.getCity(), receiver.getCounty());
            log.error(message);
            throw new SaasException(message);
        }
        
        // heavy(kg) = max(重量, 体积重量)
        Pair<String, BigDecimal> heavyPair = calHeavy(goods);
        waybill.setHeavyType(heavyPair.getLeft());
        waybill.setHeavy(heavyPair.getRight());
        
        // 临沂市-兰山区-兰山街道办事处
        // 35.1165    118.266583
        // 临沂散货点 -> 收货地址的市区中心
        PlaceInfo place = BaiduMapApi.calPlaceInfo(receiver.getProvince() + receiver.getCity() + receiver.getCounty(), receiver.getCity());
        RouteInfo route = BaiduMapApi.calRouteInfo(new BigDecimal(35.1165), new BigDecimal(118.266583), place.getLat(), place.getLng());
        
        /**
         * N单价元/吨 * max(重量, 体积重量) * 折扣率
         */
        // heavy * (直达重货价格 + 中转重货价格) * discount
        BigDecimal heavy = heavyPair.getRight();
        BigDecimal discount = calWeightDiscount(lineOffer, heavy);
        BigDecimal zhonghuoJiage = new BigDecimal(lineOffer.getGanxianZhongJiage()).add(new BigDecimal(lineOffer.getZhongzhuanZhongJiage()));
        BigDecimal totalJiage = new BigDecimal(lineOffer.getGanxianZhongJiage()).add(new BigDecimal(lineOffer.getZhongzhuanZhongJiage())).add(new BigDecimal(lineOffer.getZhixianZhongJiage()));
    
        BigDecimal estimatePrice = heavy.multiply(zhonghuoJiage).divide(totalJiage, 2, RoundingMode.HALF_UP);
        estimatePrice = estimatePrice.multiply(discount);
    
        // 货品加价 markup
        BigDecimal markup = calGoodsTypeMarkup(goods);
        estimatePrice = estimatePrice.multiply(markup);
        
        // MAX(计算值，起步价)
        if (estimatePrice.compareTo(new BigDecimal(lineOffer.getQibuJiage())) < 0) {
                estimatePrice = new BigDecimal(lineOffer.getQibuJiage());
        }
        
        waybill.setDistance(route.getDistance());
        waybill.setDuration(lineOffer.getQuanchengShixiao().max(new BigDecimal(24 * 60 * 60)).intValue());
        waybill.setEstimatePrice(estimatePrice);
        waybill.setPaymentPrice(null);
        waybill.setRealPrice(null);
        
        waybill.setSrcProvince("山东省");
        waybill.setSrcCity("临沂市");
        waybill.setSrcCounty("兰山区");
        waybill.setSrcAddressDetail("临西十二路兰山街道办事处朱许小学东南420米");
        waybill.setSrcAreaCode("371302");
        waybill.setSrcStationId(10001L);
        
        waybill.setDstProvince(place.getProvince());
        waybill.setDstCity(place.getCity());
        waybill.setDstCounty(place.getDistrict());
        waybill.setDstAddressDetail(place.getName());
        waybill.setDstAreaCode(place.getAdcode());
        waybill.setDstStationId(null);
        
        waybill.setState("pending");
        waybill.setStateTime(new Date());
        waybill.setCreateTime(new Date());
        waybill.setUpdateTime(new Date());
        
        return waybill;
    }
    
    public Pair<String, BigDecimal> calHeavy(PiaoOrderGoodsReq goods) {
        // kg
        BigDecimal heavy = goods.getTotalBulk().multiply(new BigDecimal(1000000/3000));
        if (goods.getTotalWeight().compareTo(heavy) >= 0) {
            return Pair.of("计重", goods.getTotalWeight());
        } else {
            return Pair.of("计抛", heavy);
        }
    }
    
    public BigDecimal calWeightDiscount(LineOfferEntity lineOffer, BigDecimal heavy) {
        // kg
        if (heavy.compareTo(new BigDecimal(1000)) > 0) {
            return lineOffer.getPrice1000();
        } else if (heavy.compareTo(new BigDecimal(950)) > 0) {
            return lineOffer.getPrice9501000();
        } else if (heavy.compareTo(new BigDecimal(900)) > 0) {
            return lineOffer.getPrice900950();
        } else if (heavy.compareTo(new BigDecimal(850)) > 0) {
            return lineOffer.getPrice850900();
        } else if (heavy.compareTo(new BigDecimal(800)) > 0) {
            return lineOffer.getPrice800850();
        } else if (heavy.compareTo(new BigDecimal(750)) > 0) {
            return lineOffer.getPrice750800();
        } else if (heavy.compareTo(new BigDecimal(700)) > 0) {
            return lineOffer.getPrice700750();
        } else if (heavy.compareTo(new BigDecimal(650)) > 0) {
            return lineOffer.getPrice650700();
        } else if (heavy.compareTo(new BigDecimal(600)) > 0) {
            return lineOffer.getPrice600650();
        } else if (heavy.compareTo(new BigDecimal(550)) > 0) {
            return lineOffer.getPrice550600();
        } else if (heavy.compareTo(new BigDecimal(500)) > 0) {
            return lineOffer.getPrice500550();
        } else if (heavy.compareTo(new BigDecimal(450)) > 0) {
            return lineOffer.getPrice450500();
        } else if (heavy.compareTo(new BigDecimal(400)) > 0) {
            return lineOffer.getPrice400450();
        } else if (heavy.compareTo(new BigDecimal(350)) > 0) {
            return lineOffer.getPrice350400();
        } else if (heavy.compareTo(new BigDecimal(300)) > 0) {
            return lineOffer.getPrice300350();
        } else if (heavy.compareTo(new BigDecimal(250)) > 0) {
            return lineOffer.getPrice250300();
        } else if (heavy.compareTo(new BigDecimal(200)) > 0) {
            return lineOffer.getPrice200250();
        } else if (heavy.compareTo(new BigDecimal(150)) > 0) {
            return lineOffer.getPrice150200();
        } else if (heavy.compareTo(new BigDecimal(100)) > 0) {
            return lineOffer.getPrice100150();
        } else if (heavy.compareTo(new BigDecimal(50)) > 0) {
            return lineOffer.getPrice50100();
        } else if (heavy.compareTo(new BigDecimal(20)) > 0) {
            return lineOffer.getPrice2050();
        } else {
            return new BigDecimal(1);
        }
    }
    
    public BigDecimal calGoodsTypeMarkup(PiaoOrderGoodsReq goods) {
        String goodsType = goods.getGoodsType();
        // 机械设备	60%
        // 陶瓷	20%
        // 化工品	10%
        // 其他	10%
        if (goodsType.equalsIgnoreCase("机械设备")) {
            return new BigDecimal(1.6);
        } else if (goodsType.equalsIgnoreCase("陶瓷")) {
            return new BigDecimal(1.2);
        } else if (goodsType.equalsIgnoreCase("化工品")) {
            return new BigDecimal(1.1);
        } else if (goodsType.equalsIgnoreCase("陶瓷")) {
            return new BigDecimal(1.1);
        } else {
            return new BigDecimal(1.0);
        }
    }
    
    public BigDecimal calPickDistancePrice(LineOfferEntity lineOffer, Integer distance) {
        //（T公里-5）*续费公里/元)
        BigDecimal estimatePrice = new BigDecimal(0);
        if (distance > 50000) {
            BigDecimal buf = new BigDecimal(distance / 1000).subtract(new BigDecimal(50)).multiply(lineOffer.getQuhuo50());
            estimatePrice = estimatePrice.add(buf);
            distance = 50000;
        }
        if (distance > 25000) {
            BigDecimal buf = new BigDecimal(distance / 1000).subtract(new BigDecimal(25)).multiply(lineOffer.getQuhuo2550());
            estimatePrice = estimatePrice.add(buf);
            distance = 25000;
        }
        if (distance > 5000) {
            BigDecimal buf = new BigDecimal(distance / 1000).subtract(new BigDecimal(5)).multiply(lineOffer.getQuhuo525());
            estimatePrice = estimatePrice.add(buf);
            // distance = 5000;
        }
        return estimatePrice;
    }
    
}
